<template>
  <div class="line-chart-container">
    <div class="chart-header">
      <div class="zoom-controls">
        <div class="time-range-selector">
          <label>时间范围:</label>
          <select v-model="timeRange" @change="onTimeRangeChange">
            <option value="day">1天</option>
            <option value="week">1周</option>
            <option value="custom">自定义</option>
          </select>
        </div>
        <div v-if="timeRange === 'custom'" class="date-range-selector">
          <label>起始日期:</label>
          <input
            type="date"
            v-model="startDateString"
            @change="onDateRangeChange"
          />
          <label>结束日期:</label>
          <input
            type="date"
            v-model="endDateString"
            @change="onDateRangeChange"
          />
        </div>
        <span>缩放: {{ Math.round(zoomLevel * 100) }}%</span>
        <span style="margin-left: 10px; font-size: 12px; color: #666;">
          精细网格: {{ fineGridSubdivisionCount }}等分 ({{
            fineGridLines.length
          }}条线) X轴: {{ xAxisTicks.length }}个刻度, Y轴:
          {{ yAxisTicks.length }}个刻度
        </span>
        <span style="margin-left: 10px; font-size: 12px; color: #666;">
          图号: {{ drawingInfo.drawingNumber }}
        </span>
        <div class="zoom-mode-selector">
          <button
            @click="setZoomMode('global')"
            :class="{ active: zoomMode === 'global' }"
          >
            全局视图
          </button>
          <button
            @click="setZoomMode('detail')"
            :class="{ active: zoomMode === 'detail' }"
          >
            细节视图
          </button>
        </div>
        <button @click="resetZoom">重置</button>
        <button @click="printChart">打印</button>
        <button @click="exportAsImage">导出图片</button>
      </div>
    </div>

    <!-- 图纸信息表格 - 移到图表上方，支持编辑 -->
    <div class="drawing-info-header">
      <div
        class="drawing-info-editable"
        style="display: flex !important; flex-wrap: wrap !important; gap: 6px 10px !important; justify-content: center !important; align-items: center !important;"
      >
        <div class="info-item">
          <label>图号：</label>
          <input v-model="drawingInfo.drawingNumber" class="editable-input" />
        </div>
        <div class="info-item">
          <label>设备号：</label>
          <input v-model="drawingInfo.equipmentNumber" class="editable-input" />
        </div>
        <div class="info-item">
          <label>制图：</label>
          <input v-model="drawingInfo.drawingBy" class="editable-input" />
        </div>
        <div class="info-item">
          <label>检验：</label>
          <input v-model="drawingInfo.inspector" class="editable-input" />
        </div>
        <div class="info-item" v-if="drawingInfo.approvalBy">
          <label>审核：</label>
          <input v-model="drawingInfo.approvalBy" class="editable-input" />
        </div>
        <div class="info-item" v-if="drawingInfo.date">
          <label>日期：</label>
          <input v-model="drawingInfo.date" class="editable-input" />
        </div>
        <div class="info-item" v-if="drawingInfo.scale">
          <label>比例：</label>
          <input v-model="drawingInfo.scale" class="editable-input" />
        </div>
        <div class="info-item" v-if="drawingInfo.material">
          <label>材料：</label>
          <input v-model="drawingInfo.material" class="editable-input" />
        </div>
      </div>
    </div>

    <div
      ref="chartContainer"
      class="chart-wrapper"
      @wheel="handleWheel"
      @mousedown="handleMouseDown"
      @mousemove="handleMouseMove"
      @mouseup="handleMouseUp"
      @mouseleave="handleMouseUp"
    >
      <!-- 网格背景 -->
      <svg
        class="grid-svg"
        :width="containerWidth"
        :height="containerHeight"
        :viewBox="`0 0 ${containerWidth} ${containerHeight}`"
      >
        <!-- 网格线 -->
        <g class="grid-lines">
          <!-- 精细网格线 -->
          <g v-for="(tick, index) in fineGridLines" :key="`fine-${index}`">
            <!-- 垂直精细网格线 -->
            <line
              v-if="tick.type === 'vertical'"
              :x1="tick.x1"
              :y1="tick.y1"
              :x2="tick.x2"
              :y2="tick.y2"
              stroke="#e0e0e0"
              stroke-width="1"
            />
            <!-- 水平精细网格线 -->
            <line
              v-if="tick.type === 'horizontal'"
              :x1="tick.x1"
              :y1="tick.y1"
              :x2="tick.x2"
              :y2="tick.y2"
              stroke="#e0e0e0"
              stroke-width="1"
            />
          </g>

          <!-- 主网格线 -->
          <g v-for="(tick, index) in mainGridLines" :key="`main-${index}`">
            <!-- 垂直主网格线 -->
            <line
              v-if="tick.type === 'vertical'"
              :x1="tick.x1"
              :y1="tick.y1"
              :x2="tick.x2"
              :y2="tick.y2"
              stroke="#e0e0e0"
              stroke-width="1"
            />
            <!-- 水平主网格线 -->
            <line
              v-if="tick.type === 'horizontal'"
              :x1="tick.x1"
              :y1="tick.y1"
              :x2="tick.x2"
              :y2="tick.y2"
              stroke="#e0e0e0"
              stroke-width="1"
            />
          </g>
        </g>

        <!-- 坐标轴 -->
        <g class="axes">
          <!-- X轴 -->
          <line
            :x1="paddingLeft"
            :y1="containerHeight - paddingBottom"
            :x2="containerWidth - paddingRight"
            :y2="containerHeight - paddingBottom"
            stroke="#333"
            stroke-width="2"
          />
          <!-- Y轴 -->
          <line
            :x1="paddingLeft"
            :y1="paddingTop"
            :x2="paddingLeft"
            :y2="containerHeight - paddingBottom"
            stroke="#333"
            stroke-width="2"
          />
        </g>

        <!-- 标尺刻度 -->
        <g class="ruler-marks">
          <!-- X轴刻度 -->
          <g v-for="(tick, index) in xAxisTicks" :key="`x-${index}`">
            <line
              :x1="tick.x"
              :y1="containerHeight - paddingBottom"
              :x2="tick.x"
              :y2="containerHeight - paddingBottom + 5"
              stroke="#333"
              stroke-width="1"
            />
            <text
              :x="tick.x"
              :y="containerHeight - paddingBottom + 15"
              text-anchor="middle"
              font-size="12"
              fill="#333"
            >
              {{ tick.label }}
            </text>
          </g>

          <!-- Y轴刻度 -->
          <g v-for="(tick, index) in yAxisTicks" :key="`y-${index}`">
            <line
              :x1="paddingLeft"
              :y1="tick.y"
              :x2="paddingLeft - 5"
              :y2="tick.y"
              stroke="#333"
              stroke-width="1"
            />
            <text
              :x="paddingLeft - 15"
              :y="tick.y + 4"
              text-anchor="end"
              font-size="12"
              fill="#333"
            >
              {{ tick.label }}
            </text>
          </g>
        </g>

        <!-- 折线图 -->
        <g class="line-chart">
          <path :d="linePath" fill="none" stroke="#ff4d4f" stroke-width="2" />

          <!-- 数据点 -->
          <circle
            v-for="(point, index) in chartPoints"
            :key="`point-${index}`"
            :cx="point.x"
            :cy="point.y"
            :r="getPointRadius(index)"
            :fill="getPointColor(index)"
            stroke="#fff"
            stroke-width="2"
            @mouseenter="showTooltip($event, index)"
            @mouseleave="hideTooltip"
            style="cursor: pointer;"
          />

          <!-- 异常值标签 -->
          <text
            v-for="(item, index) in outlierLabels"
            :key="`label-${index}`"
            :x="item.point.x"
            :y="getLabelY(item.point.y, item.value)"
            text-anchor="middle"
            font-size="10"
            fill="#ff4d4f"
            font-weight="bold"
          >
            {{ item.value.toFixed(1) }}°C
          </text>
        </g>
      </svg>

      <!-- 悬停提示框 -->
      <div
        v-if="tooltip.visible"
        class="tooltip"
        :style="{
          left: tooltip.x + 'px',
          top: tooltip.y + 'px'
        }"
      >
        {{ tooltip.value }}°C
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Ref, Vue } from 'vue-property-decorator';

interface Point {
  x: number;
  y: number;
}

interface Tick {
  x?: number;
  y?: number;
  label: string;
}

interface DrawingInfo {
  drawingNumber: string; // 图号
  equipmentNumber: string; // 设备号
  drawingBy: string; // 制图人
  inspector: string; // 检验员
  approvalBy?: string; // 审核人
  date?: string; // 日期
  scale?: string; // 比例
  material?: string; // 材料
  remarks?: string; // 备注
}

@Component
export default class LineChartWithRuler extends Vue {
  @Ref('chartContainer') chartContainer!: HTMLElement;

  // Props
  drawingInfo: DrawingInfo = {
    drawingNumber: 'T-001',
    equipmentNumber: 'EQ-2024-001',
    drawingBy: '张三',
    inspector: '李四',
    approvalBy: '王五',
    date: new Date().toLocaleDateString(),
    scale: '1:1',
    material: '不锈钢',
    remarks: '温度监控图表'
  };

  // 容器尺寸
  containerWidth = 1200;

  containerHeight = 800;

  padding = 60;

  paddingLeft = 80;

  paddingRight = 20;

  paddingTop = 20;

  paddingBottom = 50;

  // 网格和缩放
  gridSize = 20;

  // 基础网格大小
  zoomLevel = 1;

  minZoom = 0.1;

  maxZoom = 5;

  // 拖拽状态
  isDragging = false;

  lastMouseX = 0;

  lastMouseY = 0;

  translateX = 0;

  translateY = 0;

  // 时间范围配置
  timeRange = 'day'; // 'day', 'week'

  // 日期范围
  startDate = new Date();

  endDate = new Date();

  // 缩放模式
  zoomMode: 'global' | 'detail' = 'global';

  // 悬停提示框
  tooltip = {
    visible: false,
    x: 0,
    y: 0,
    value: 0
  };

  // 温度数据 - 根据时间范围生成
  sampleData: Point[] = this.generateTemperatureData();

  // 计算属性
  get startDateString(): string {
    return this.startDate.toISOString().split('T')[0];
  }

  set startDateString(value: string) {
    this.startDate = new Date(value);
  }

  get endDateString(): string {
    return this.endDate.toISOString().split('T')[0];
  }

  set endDateString(value: string) {
    this.endDate = new Date(value);
  }

  get chartTitle(): string {
    if (this.timeRange === 'custom') {
      const startStr = this.startDate.toLocaleDateString();
      const endStr = this.endDate.toLocaleDateString();
      return `(${startStr} - ${endStr})`;
    }
    if (this.timeRange === 'week') {
      return '(最近7天)';
    }
    return '(最近1天)';
  }

  // 精细网格大小 - 根据缩放级别调整
  get fineGridSize(): number {
    if (this.zoomLevel >= 3) {
      return 5; // 高倍缩放时，精细网格为5px
    }
    if (this.zoomLevel >= 2) {
      return 10; // 中等缩放时，精细网格为10px
    }
    if (this.zoomLevel >= 1) {
      return 20; // 正常缩放时，精细网格为20px
    }
    return 40; // 缩小视图时，精细网格为40px
  }

  // 精细网格细分数量 - 用于调试显示
  get fineGridSubdivisionCount(): number {
    if (this.zoomLevel >= 4) return 10; // 超高倍缩放：10等分
    if (this.zoomLevel >= 3) return 8; // 高倍缩放：8等分
    if (this.zoomLevel >= 2) return 5; // 中高倍缩放：5等分
    if (this.zoomLevel >= 1.5) return 4; // 中倍缩放：4等分
    if (this.zoomLevel >= 1) return 3; // 正常缩放：3等分
    return 2; // 缩小：2等分
  }

  // 异常值标签 - 只在全局视图显示
  get outlierLabels(): Array<{ point: Point; value: number }> {
    if (this.zoomMode !== 'global') return [];

    const labels: Array<{ point: Point; value: number }> = [];
    this.chartPoints.forEach((point, index) => {
      if (this.isOutlier(index)) {
        labels.push({
          point,
          value: this.getOriginalValue(index)
        });
      }
    });
    return labels;
  }

  // 主网格线 - 完全覆盖XY轴围成的区域
  get mainGridLines(): Array<{
    type: 'vertical' | 'horizontal';
    x1: number;
    y1: number;
    x2: number;
    y2: number;
  }> {
    const lines: Array<{
      type: 'vertical' | 'horizontal';
      x1: number;
      y1: number;
      x2: number;
      y2: number;
    }> = [];

    // 定义网格区域边界
    const gridLeft = this.paddingLeft;
    const gridRight = this.containerWidth - this.paddingRight;
    const gridTop = this.paddingTop;
    const gridBottom = this.containerHeight - this.paddingBottom;

    // 垂直主网格线 - 与X轴刻度对齐
    const xTicks = this.xAxisTicks;
    xTicks.forEach(tick => {
      if (tick.x !== undefined) {
        lines.push({
          type: 'vertical',
          x1: tick.x,
          y1: gridTop,
          x2: tick.x,
          y2: gridBottom
        });
      }
    });

    // 水平主网格线 - 与Y轴刻度对齐
    const yTicks = this.yAxisTicks;
    yTicks.forEach(tick => {
      if (tick.y !== undefined) {
        lines.push({
          type: 'horizontal',
          x1: gridLeft,
          y1: tick.y,
          x2: gridRight,
          y2: tick.y
        });
      }
    });

    return lines;
  }

  // 精细网格线 - 在刻度之间添加更细的网格，完全覆盖XY轴区域
  get fineGridLines(): Array<{
    type: 'vertical' | 'horizontal';
    x1: number;
    y1: number;
    x2: number;
    y2: number;
  }> {
    const lines: Array<{
      type: 'vertical' | 'horizontal';
      x1: number;
      y1: number;
      x2: number;
      y2: number;
    }> = [];

    // 定义网格区域边界
    const gridLeft = this.paddingLeft;
    const gridRight = this.containerWidth - this.paddingRight;
    const gridTop = this.paddingTop;
    const gridBottom = this.containerHeight - this.paddingBottom;

    // 根据缩放级别确定细分数量
    const getSubdivisionCount = (): number => {
      if (this.zoomLevel >= 4) return 10; // 超高倍缩放：10等分
      if (this.zoomLevel >= 3) return 8; // 高倍缩放：8等分
      if (this.zoomLevel >= 2) return 5; // 中高倍缩放：5等分
      if (this.zoomLevel >= 1.5) return 4; // 中倍缩放：4等分
      if (this.zoomLevel >= 1) return 3; // 正常缩放：3等分
      return 2; // 缩小：2等分
    };

    const subdivisionCount = getSubdivisionCount();

    // 垂直精细网格线
    const xTicks = this.xAxisTicks;
    for (let i = 0; i < xTicks.length - 1; i++) {
      const startX = xTicks[i].x || 0;
      const endX = xTicks[i + 1].x || 0;
      const segmentWidth = (endX - startX) / subdivisionCount;

      for (let j = 1; j < subdivisionCount; j++) {
        const x = startX + j * segmentWidth;
        lines.push({
          type: 'vertical',
          x1: x,
          y1: gridTop,
          x2: x,
          y2: gridBottom
        });
      }
    }

    // 水平精细网格线
    const yTicks = this.yAxisTicks;
    for (let i = 0; i < yTicks.length - 1; i++) {
      const startY = yTicks[i].y || 0;
      const endY = yTicks[i + 1].y || 0;
      const segmentHeight = (endY - startY) / subdivisionCount;

      for (let j = 1; j < subdivisionCount; j++) {
        const y = startY + j * segmentHeight;
        lines.push({
          type: 'horizontal',
          x1: gridLeft,
          y1: y,
          x2: gridRight,
          y2: y
        });
      }
    }

    return lines;
  }

  get chartPoints(): Point[] {
    const chartWidth =
      this.containerWidth - this.paddingLeft - this.paddingRight;
    const chartHeight =
      this.containerHeight - this.paddingTop - this.paddingBottom;

    // 根据时间范围确定X轴范围
    const { maxX, minX } = this.getTimeRange();

    // 动态计算Y轴范围
    const { maxY, minY } = this.getTemperatureRange();

    return this.sampleData.map(point => ({
      x: this.paddingLeft + ((point.x - minX) / (maxX - minX)) * chartWidth,
      y:
        this.paddingTop +
        chartHeight -
        ((point.y - minY) / (maxY - minY)) * chartHeight
    }));
  }

  get linePath(): string {
    if (this.chartPoints.length === 0) return '';

    let path = `M ${this.chartPoints[0].x} ${this.chartPoints[0].y}`;
    for (let i = 1; i < this.chartPoints.length; i++) {
      path += ` L ${this.chartPoints[i].x} ${this.chartPoints[i].y}`;
    }
    return path;
  }

  get xAxisTicks(): Tick[] {
    const ticks: Tick[] = [];
    const chartWidth =
      this.containerWidth - this.paddingLeft - this.paddingRight;
    const { minX, maxX } = this.getTimeRange();
    const timeRange = maxX - minX;

    // 根据缩放级别动态调整刻度数量
    let tickCount: number;
    if (this.zoomLevel >= 4) {
      tickCount = Math.floor(chartWidth / 10); // 超高倍缩放：密集刻度
    } else if (this.zoomLevel >= 3) {
      tickCount = Math.floor(chartWidth / 15); // 高倍缩放：较密集刻度
    } else if (this.zoomLevel >= 2) {
      tickCount = Math.floor(chartWidth / 20); // 中高倍缩放：中等刻度
    } else if (this.zoomLevel >= 1) {
      tickCount = Math.floor(chartWidth / 30); // 正常缩放：标准刻度
    } else if (this.zoomLevel >= 0.5) {
      tickCount = Math.floor(chartWidth / 40); // 缩小：稀疏刻度
    } else {
      tickCount = Math.floor(chartWidth / 60); // 最小：最稀疏刻度
    }

    // 确保刻度数量在合理范围内
    tickCount = Math.max(3, Math.min(tickCount, 20));

    // 计算时间步长
    const timeStep = timeRange / tickCount;

    for (let i = 0; i <= tickCount; i++) {
      const x = this.paddingLeft + (i / tickCount) * chartWidth;
      const timeValue = minX + i * timeStep;

      // 格式化时间标签
      const label = this.formatTimeLabel(timeValue);

      ticks.push({
        x,
        label
      });
    }

    // 确保第一个刻度在Y轴位置，最后一个刻度在X轴右端点
    if (ticks.length > 0) {
      ticks[0].x = this.paddingLeft; // 第一个刻度在Y轴
      ticks[ticks.length - 1].x = this.containerWidth - this.paddingRight; // 最后一个刻度在X轴右端点
    }
    return ticks;
  }

  get yAxisTicks(): Tick[] {
    const ticks: Tick[] = [];
    const chartHeight =
      this.containerHeight - this.paddingTop - this.paddingBottom;
    const { minY, maxY } = this.getTemperatureRange();
    const tempRange = maxY - minY;

    // 根据缩放级别动态调整刻度数量
    let tickCount: number;
    if (this.zoomLevel >= 4) {
      tickCount = Math.floor(chartHeight / 15); // 超高倍缩放：密集刻度
    } else if (this.zoomLevel >= 3) {
      tickCount = Math.floor(chartHeight / 20); // 高倍缩放：较密集刻度
    } else if (this.zoomLevel >= 2) {
      tickCount = Math.floor(chartHeight / 25); // 中高倍缩放：中等刻度
    } else if (this.zoomLevel >= 1) {
      tickCount = Math.floor(chartHeight / 30); // 正常缩放：标准刻度
    } else if (this.zoomLevel >= 0.5) {
      tickCount = Math.floor(chartHeight / 40); // 缩小：稀疏刻度
    } else {
      tickCount = Math.floor(chartHeight / 50); // 最小：最稀疏刻度
    }

    // 确保刻度数量在合理范围内
    tickCount = Math.max(3, Math.min(tickCount, 15));

    // 生成合适的刻度值
    const tickValues = this.generateNiceTicks(minY, maxY, tickCount);

    tickValues.forEach(tempValue => {
      const y =
        this.paddingTop + ((maxY - tempValue) / tempRange) * chartHeight;
      ticks.push({
        y,
        label: `${tempValue.toFixed(3)}°C`
      });
    });

    // 确保第一个刻度在X轴位置，最后一个刻度在Y轴顶部
    if (ticks.length > 0) {
      ticks[0].y = this.containerHeight - this.paddingBottom; // 第一个刻度在X轴
      ticks[ticks.length - 1].y = this.paddingTop; // 最后一个刻度在Y轴顶部
    }

    return ticks;
  }

  // 格式化时间标签
  formatTimeLabel(minutes: number): string {
    if (this.timeRange === 'custom') {
      const actualDate = new Date(
        this.startDate.getTime() + minutes * 60 * 1000
      );
      const days = Math.floor(minutes / (24 * 60));
      const hours = Math.floor((minutes % (24 * 60)) / 60);
      const mins = Math.floor(minutes % 60);

      if (days > 0) {
        return `${days}天${hours}时`;
      }
      if (hours > 0) {
        return `${hours}:${mins.toString().padStart(2, '0')}`;
      }
      return `${mins}分`;
    }
    if (this.timeRange === 'week') {
      const days = Math.floor(minutes / (24 * 60));
      const hours = Math.floor((minutes % (24 * 60)) / 60);
      if (days > 0) {
        return `${days}天${hours}时`;
      }
      return `${hours}时`;
    }
    const hours = Math.floor(minutes / 60);
    const mins = Math.floor(minutes % 60);
    if (hours > 0) {
      return `${hours}:${mins.toString().padStart(2, '0')}`;
    }
    return `${mins}分`;
  }

  // 生成合适的刻度值，避免重复
  generateNiceTicks(min: number, max: number, targetTicks?: number): number[] {
    const range = max - min;
    const ticks =
      targetTicks || (this.zoomLevel >= 2 ? 6 : this.zoomLevel >= 1 ? 5 : 4);

    // 计算合适的步长
    const step = range / (ticks - 1);

    // 将步长调整为"好看"的数字
    const magnitude = 10 ** Math.floor(Math.log10(step));
    const normalizedStep = step / magnitude;

    let niceStep: number;
    if (normalizedStep <= 1) {
      niceStep = 1 * magnitude;
    } else if (normalizedStep <= 2) {
      niceStep = 2 * magnitude;
    } else if (normalizedStep <= 5) {
      niceStep = 5 * magnitude;
    } else {
      niceStep = 10 * magnitude;
    }

    // 生成刻度值
    const result: number[] = [];
    const start = Math.ceil(min / niceStep) * niceStep;

    for (let value = start; value <= max + niceStep / 2; value += niceStep) {
      if (value >= min && value <= max) {
        result.push(value);
      }
    }

    // 确保包含最小值和最大值
    if (result.length === 0 || result[0] > min) {
      result.unshift(min);
    }
    if (result.length === 0 || result[result.length - 1] < max) {
      result.push(max);
    }

    return result.sort((a, b) => a - b);
  }

  // 获取时间范围
  getTimeRange(): { minX: number; maxX: number } {
    if (this.timeRange === 'custom') {
      const timeDiff = this.endDate.getTime() - this.startDate.getTime();
      const minutesDiff = Math.floor(timeDiff / (1000 * 60));
      return { minX: 0, maxX: minutesDiff };
    }
    if (this.timeRange === 'week') {
      return { minX: 0, maxX: 7 * 24 * 60 }; // 7天，以分钟为单位
    }
    return { minX: 0, maxX: 24 * 60 }; // 1天，以分钟为单位
  }

  // 获取温度范围
  getTemperatureRange(): { minY: number; maxY: number } {
    if (this.sampleData.length === 0) {
      return { minY: 26.8, maxY: 27.5 };
    }

    const temperatures = this.sampleData.map(p => p.y);
    const minTemp = Math.min(...temperatures);
    const maxTemp = Math.max(...temperatures);
    const tempRange = maxTemp - minTemp;

    // 检测异常值
    const { normalRange, hasOutliers } = this.detectOutliers(temperatures);

    // 根据缩放级别智能调整显示范围
    return this.calculateSmartRange(temperatures, normalRange, hasOutliers);
  }

  // 智能计算显示范围
  calculateSmartRange(
    temperatures: number[],
    normalRange: { min: number; max: number },
    hasOutliers: boolean
  ): { minY: number; maxY: number } {
    const minTemp = Math.min(...temperatures);
    const maxTemp = Math.max(...temperatures);
    const totalRange = maxTemp - minTemp;
    const normalTempRange = normalRange.max - normalRange.min;

    // 根据缩放模式和缩放级别决定显示策略
    if (this.zoomMode === 'detail') {
      // 细节模式：优先显示正常范围，突出小数级变化
      if (normalTempRange < 1) {
        const margin = Math.max(normalTempRange * 0.2, 0.05);
        return {
          minY: normalRange.min - margin,
          maxY: normalRange.max + margin
        };
      }
      const margin = normalTempRange * 0.1;
      return {
        minY: normalRange.min - margin,
        maxY: normalRange.max + margin
      };
    }

    // 全局模式：根据缩放级别调整
    if (this.zoomLevel >= 3) {
      // 高倍缩放：显示正常范围，突出细节
      if (normalTempRange < 1) {
        const margin = Math.max(normalTempRange * 0.2, 0.05);
        return {
          minY: normalRange.min - margin,
          maxY: normalRange.max + margin
        };
      }
      const margin = normalTempRange * 0.1;
      return {
        minY: normalRange.min - margin,
        maxY: normalRange.max + margin
      };
    }
    if (this.zoomLevel >= 2) {
      // 中等缩放：平衡显示
      if (hasOutliers && normalTempRange < totalRange * 0.3) {
        const margin = Math.max(normalTempRange * 0.15, 0.1);
        return {
          minY: normalRange.min - margin,
          maxY: normalRange.max + margin
        };
      }
      const margin = totalRange * 0.05;
      return {
        minY: minTemp - margin,
        maxY: maxTemp + margin
      };
    }
    if (this.zoomLevel >= 1) {
      // 正常缩放：显示全部范围
      const margin = totalRange * 0.05;
      return {
        minY: minTemp - margin,
        maxY: maxTemp + margin
      };
    }
    // 缩小视图：显示全部范围，包括异常值
    const margin = totalRange * 0.1;
    return {
      minY: minTemp - margin,
      maxY: maxTemp + margin
    };
  }

  // 检测异常值
  detectOutliers(
    temperatures: number[]
  ): { normalRange: { min: number; max: number }; hasOutliers: boolean } {
    if (temperatures.length < 3) {
      return {
        normalRange: {
          min: Math.min(...temperatures),
          max: Math.max(...temperatures)
        },
        hasOutliers: false
      };
    }

    // 计算中位数和四分位数
    const sorted = [...temperatures].sort((a, b) => a - b);
    const q1 = sorted[Math.floor(sorted.length * 0.25)];
    const q3 = sorted[Math.floor(sorted.length * 0.75)];
    const iqr = q3 - q1;

    // 定义异常值边界
    const lowerBound = q1 - 1.5 * iqr;
    const upperBound = q3 + 1.5 * iqr;

    // 检查是否有异常值
    const outliers = temperatures.filter(
      temp => temp < lowerBound || temp > upperBound
    );
    const normalTemps = temperatures.filter(
      temp => temp >= lowerBound && temp <= upperBound
    );

    if (outliers.length > 0 && outliers.length < temperatures.length * 0.1) {
      // 如果异常值少于10%，认为是异常值
      return {
        normalRange: {
          min: Math.min(...normalTemps),
          max: Math.max(...normalTemps)
        },
        hasOutliers: true
      };
    }

    return {
      normalRange: {
        min: Math.min(...temperatures),
        max: Math.max(...temperatures)
      },
      hasOutliers: false
    };
  }

  // 计算双Y轴范围
  calculateDualAxisRange(
    normalRange: { min: number; max: number },
    allTemperatures: number[]
  ): { minY: number; maxY: number } {
    const normalTempRange = normalRange.max - normalRange.min;

    // 如果正常范围很小（小于1度），使用正常范围
    if (normalTempRange < 1) {
      const margin = Math.max(normalTempRange * 0.2, 0.05);
      return {
        minY: normalRange.min - margin,
        maxY: normalRange.max + margin
      };
    }

    // 否则使用全部数据范围，但添加适当边距
    const minTemp = Math.min(...allTemperatures);
    const maxTemp = Math.max(...allTemperatures);
    const totalRange = maxTemp - minTemp;
    const margin = totalRange * 0.05; // 5%边距

    return {
      minY: minTemp - margin,
      maxY: maxTemp + margin
    };
  }

  // 生成温度数据
  generateTemperatureData(): Point[] {
    const data: Point[] = [];
    const { maxX } = this.getTimeRange();

    // 根据时间范围确定数据点数量
    let dataPointCount: number;
    if (this.timeRange === 'custom') {
      dataPointCount = Math.max(100, Math.floor(maxX / 10)); // 每10分钟一个点
    } else if (this.timeRange === 'week') {
      dataPointCount = 168; // 一周168小时
    } else {
      dataPointCount = 144; // 一天144个点（每10分钟一个）
    }

    const interval = maxX / dataPointCount;

    // 基础温度，模拟更小的温度变化范围
    const baseTemp = 27.03;
    const tempVariation = 0.02; // 温度变化范围 ±0.02°C

    for (let i = 0; i < dataPointCount; i++) {
      const time = i * interval;

      // 使用多个正弦波叠加模拟复杂的温度变化
      const wave1 = Math.sin((i / dataPointCount) * Math.PI * 4) * 0.01;
      const wave2 = Math.sin((i / dataPointCount) * Math.PI * 12) * 0.005;
      const randomNoise = (Math.random() - 0.5) * 0.003;

      let temperature = baseTemp + wave1 + wave2 + randomNoise;

      // 随机添加一些异常值来测试功能
      if (Math.random() < 0.05) {
        // 5%的概率出现异常值
        if (Math.random() < 0.5) {
          temperature = 23 + Math.random() * 2; // 23-25度
        } else {
          temperature = 29 + Math.random() * 2; // 29-31度
        }
      }

      data.push({
        x: time, // 时间（分钟）
        y: temperature
      });
    }

    return data;
  }

  // 根据缩放级别计算刻度步长
  getTickStep(): number {
    // 更精细的缩放级别控制，支持更大的缩放范围
    if (this.zoomLevel >= 4) return 0.5; // 超高倍缩放：30秒间隔
    if (this.zoomLevel >= 3) return 1; // 高倍缩放：1分钟间隔
    if (this.zoomLevel >= 2) return 2; // 中高倍缩放：2分钟间隔
    if (this.zoomLevel >= 1.5) return 5; // 中倍缩放：5分钟间隔
    if (this.zoomLevel >= 1) return 10; // 正常缩放：10分钟间隔
    if (this.zoomLevel >= 0.5) return 20; // 缩小：20分钟间隔
    if (this.zoomLevel >= 0.2) return 60; // 更小：1小时间隔
    return 120; // 最小：2小时间隔
  }

  // 鼠标滚轮事件处理
  handleWheel(event: WheelEvent): void {
    event.preventDefault();

    const delta = event.deltaY > 0 ? 0.9 : 1.1;
    const newZoom = this.zoomLevel * delta;

    if (newZoom >= this.minZoom && newZoom <= this.maxZoom) {
      this.zoomLevel = newZoom;
      // 移除自动模式切换，让缩放和视图模式独立工作
    }
  }

  // 鼠标按下事件
  handleMouseDown(event: MouseEvent): void {
    this.isDragging = true;
    this.lastMouseX = event.clientX;
    this.lastMouseY = event.clientY;
  }

  // 鼠标移动事件
  handleMouseMove(event: MouseEvent): void {
    if (!this.isDragging) return;

    const deltaX = event.clientX - this.lastMouseX;
    const deltaY = event.clientY - this.lastMouseY;

    this.translateX += deltaX;
    this.translateY += deltaY;

    this.lastMouseX = event.clientX;
    this.lastMouseY = event.clientY;
  }

  // 鼠标释放事件
  handleMouseUp(): void {
    this.isDragging = false;
  }

  // 重置缩放
  resetZoom(): void {
    this.zoomLevel = 1;
    this.translateX = 0;
    this.translateY = 0;
  }

  // 时间范围变化处理
  onTimeRangeChange(): void {
    // 设置默认日期范围
    if (this.timeRange === 'day') {
      this.endDate = new Date();
      this.startDate = new Date(this.endDate.getTime() - 24 * 60 * 60 * 1000);
    } else if (this.timeRange === 'week') {
      this.endDate = new Date();
      this.startDate = new Date(
        this.endDate.getTime() - 7 * 24 * 60 * 60 * 1000
      );
    }

    this.sampleData = this.generateTemperatureData();
  }

  // 日期范围变化处理
  onDateRangeChange(): void {
    if (this.startDate >= this.endDate) {
      console.warn('起始日期不能大于等于结束日期');
      return;
    }

    this.sampleData = this.generateTemperatureData();
  }

  // 设置缩放模式
  setZoomMode(mode: 'global' | 'detail'): void {
    this.zoomMode = mode;
    // 模式切换时重新计算图表
    this.$forceUpdate();
  }

  // 获取数据点的半径
  getPointRadius(index: number): number {
    if (this.isOutlier(index)) {
      return 6; // 异常值用更大的点
    }
    return 4; // 正常值用标准大小的点
  }

  // 获取数据点的颜色
  getPointColor(index: number): string {
    if (this.isOutlier(index)) {
      return '#ff1744'; // 异常值用更鲜艳的红色
    }
    return '#ff4d4f'; // 正常值用标准红色
  }

  // 判断是否为异常值
  isOutlier(index: number): boolean {
    if (index < 0 || index >= this.sampleData.length) return false;

    const temperatures = this.sampleData.map(p => p.y);
    const { normalRange } = this.detectOutliers(temperatures);

    const value = this.sampleData[index].y;
    return value < normalRange.min || value > normalRange.max;
  }

  // 获取原始数值
  getOriginalValue(index: number): number {
    if (index < 0 || index >= this.sampleData.length) return 0;
    return this.sampleData[index].y;
  }

  // 获取标签Y坐标 - 根据数值大小决定显示在点的上方还是下方
  getLabelY(pointY: number, value: number): number {
    const { minY, maxY } = this.getTemperatureRange();
    const tempRange = maxY - minY;
    const chartHeight = this.containerHeight - 2 * this.padding;

    // 计算当前值在温度范围中的相对位置
    const relativePosition = (value - minY) / tempRange;

    // 如果值在温度范围的上半部分，标签显示在点的上方
    // 如果值在温度范围的下半部分，标签显示在点的下方
    if (relativePosition > 0.5) {
      return pointY - 10; // 显示在点的上方
    }
    return pointY + 15; // 显示在点的下方
  }

  // 计算打印时的标签Y位置
  getPrintLabelY(
    pointY: number,
    value: number,
    printHeight: number,
    printPadding: number
  ): number {
    const { minY, maxY } = this.getTemperatureRange();
    const tempRange = maxY - minY;
    const relativePosition = (value - minY) / tempRange;

    // 如果值在温度范围的上半部分，标签显示在点上方
    // 如果值在温度范围的下半部分，标签显示在点下方
    if (relativePosition > 0.5) {
      return pointY - 10; // 上方
    }
    return pointY + 15; // 下方
  }

  // 显示悬停提示框
  showTooltip(event: MouseEvent, index: number): void {
    const rect = (event.target as Element)
      .closest('.chart-wrapper')
      ?.getBoundingClientRect();
    if (!rect) return;

    this.tooltip = {
      visible: true,
      x: event.clientX - rect.left,
      y: event.clientY - rect.top - 30,
      value: this.getOriginalValue(index)
    };
  }

  // 隐藏悬停提示框
  hideTooltip(): void {
    this.tooltip.visible = false;
  }

  // 打印图表
  printChart(): void {
    // 创建打印窗口
    const printWindow = window.open('', '_blank');
    if (!printWindow) {
      console.error('无法打开打印窗口，请检查浏览器设置');
      return;
    }

    // 获取当前图表数据
    const { minX, maxX } = this.getTimeRange();
    const { minY, maxY } = this.getTemperatureRange();
    const timeRangeText = this.timeRange === 'day' ? '1天' : '1周';

    // 计算最佳打印尺寸
    const printDimensions = this.calculatePrintDimensions();

    // 生成打印内容
    const printContent = `
      <!DOCTYPE html>
      <html>
      <head>
        <title>温度变化趋势图</title>
        <style>
          @page {
            size: A4 landscape;
            margin: 0.5cm;
          }
          
          body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 10px;
            background: white;
            width: 100%;
            height: 100vh;
            box-sizing: border-box;
          }
          
          .print-header {
            text-align: center;
            margin-bottom: 2px;
            border-bottom: 1px solid #333;
            padding-bottom: 1px;
          }
          
          .print-header h1 {
            margin: 0;
            color: #333;
            font-size: 12px;
          }
          
          .print-info {
            display: flex;
            justify-content: space-between;
            margin-bottom: 2px;
            font-size: 8px;
            color: #666;
            flex-wrap: wrap;
          }
          
          .print-drawing-info {
            margin-bottom: 2px;
            font-size: 7px;
          }
          
          .print-drawing-info table {
            border-collapse: collapse;
            width: 100%;
            border: 1px solid #333;
          }
          
          .print-drawing-info td {
            border: 1px solid #333;
            padding: 0px 1px;
            text-align: center;
          }
          
          .print-drawing-info .label {
            background: #f0f0f0;
            font-weight: bold;
            width: 15%;
          }
          
          .print-drawing-info .value {
            background: white;
            width: 20%;
          }
          
          .chart-container {
            width: 100%;
            height: 300px;
            border: 1px solid #ddd;
            background: white;
            display: flex;
            justify-content: center;
            align-items: center;
            overflow: hidden;
          }
          
          .chart-container svg {
            width: 100% !important;
            height: 100% !important;
            display: block !important;
          }
          
          .print-footer {
            margin-top: 2px;
            text-align: center;
            font-size: 7px;
            color: #999;
            border-top: 1px solid #ddd;
            padding-top: 1px;
          }
          
          @media print {
            body {
              -webkit-print-color-adjust: exact;
              print-color-adjust: exact;
              width: 100%;
              height: 100vh;
            }
            
            .chart-container {
              height: calc(100vh - 100px);
            }
          }
        </style>
      </head>
      <body>
        <div class="print-header">
          <h1>温度变化趋势图</h1>
        </div>
        
        <div class="print-info">
          <div>时间范围: ${timeRangeText}</div>
          <div>温度范围: ${minY.toFixed(3)}°C - ${maxY.toFixed(3)}°C</div>
        </div>
        
        <!-- 图纸信息表格 -->
        <div class="print-drawing-info">
          <table>
            <tr>
              <td class="label">图号</td>
              <td class="value">${this.drawingInfo.drawingNumber}</td>
              <td class="label">设备号</td>
              <td class="value">${this.drawingInfo.equipmentNumber}</td>
            </tr>
            <tr>
              <td class="label">制图</td>
              <td class="value">${this.drawingInfo.drawingBy}</td>
              <td class="label">检验</td>
              <td class="value">${this.drawingInfo.inspector}</td>
            </tr>
          </table>
        </div>
        
        <div class="chart-container">
          ${this.generatePrintSVG(printDimensions)}
        </div>
        
        <div class="print-footer">
          <p>此图表由温度监控系统生成</p>
        </div>
      </body>
      </html>
    `;

    // 写入内容并打印
    printWindow.document.write(printContent);
    printWindow.document.close();

    // 等待内容加载完成后打印
    printWindow.onload = () => {
      setTimeout(() => {
        printWindow.print();
        printWindow.close();
      }, 500);
    };
  }

  // 计算最佳打印尺寸
  calculatePrintDimensions(): {
    width: number;
    height: number;
    padding: number;
  } {
    // A4横向页面尺寸 (约29.7cm x 21cm)
    // 考虑边距后可用空间约27.7cm x 19cm
    // 转换为像素 (96 DPI): 约1044px x 720px
    // 为了充分利用页面宽度，使用更大的尺寸
    return {
      width: 800, // 大幅减少宽度
      height: 400, // 大幅减少高度
      padding: 30 // 大幅减少内边距
    };
  }

  // 生成打印用的SVG
  generatePrintSVG(dimensions: {
    width: number;
    height: number;
    padding: number;
  }): string {
    const { minX, maxX } = this.getTimeRange();
    const { minY, maxY } = this.getTemperatureRange();
    const timeRange = maxX - minX;
    const tempRange = maxY - minY;

    // 使用计算的最佳尺寸
    const printWidth = dimensions.width;
    const printHeight = dimensions.height;
    const printPadding = dimensions.padding;
    const chartWidth = printWidth - 2 * printPadding;
    const chartHeight = printHeight - 2 * printPadding;

    // 计算数据点位置
    const chartPoints = this.sampleData.map(point => ({
      x: printPadding + ((point.x - minX) / timeRange) * chartWidth,
      y:
        printPadding +
        chartHeight -
        ((point.y - minY) / tempRange) * chartHeight
    }));

    // 生成折线路径
    let linePath = '';
    if (chartPoints.length > 0) {
      linePath = `M ${chartPoints[0].x} ${chartPoints[0].y}`;
      for (let i = 1; i < chartPoints.length; i++) {
        linePath += ` L ${chartPoints[i].x} ${chartPoints[i].y}`;
      }
    }

    // 生成X轴刻度
    const xTicks = this.generatePrintTicks(
      minX,
      maxX,
      chartWidth,
      printPadding,
      'x'
    );
    // 生成Y轴刻度
    const yTicks = this.generatePrintTicks(
      minY,
      maxY,
      chartHeight,
      printPadding,
      'y'
    );

    return `
      <svg width="${printWidth}" height="${printHeight}" viewBox="0 0 ${printWidth} ${printHeight}" style="display: block;">
        <!-- 网格背景 -->
        <defs>
          <pattern id="printGrid" width="20" height="20" patternUnits="userSpaceOnUse">
            <path d="M 20 0 L 0 0 0 20" fill="none" stroke="#e0e0e0" stroke-width="1"/>
          </pattern>
        </defs>
        <rect x="${printPadding}" y="${printPadding}" width="${chartWidth}" height="${chartHeight}" fill="url(#printGrid)"/>
        
        <!-- 坐标轴 -->
        <line x1="${printPadding}" y1="${printHeight -
      printPadding}" x2="${printWidth - printPadding}" y2="${printHeight -
      printPadding}" stroke="#333" stroke-width="2"/>
        <line x1="${printPadding}" y1="${printPadding}" x2="${printPadding}" y2="${printHeight -
      printPadding}" stroke="#333" stroke-width="2"/>
        
        <!-- X轴刻度 -->
        ${xTicks
          .map(
            tick => `
          <line x1="${tick.x}" y1="${printHeight - printPadding}" x2="${
              tick.x
            }" y2="${printHeight -
              printPadding +
              5}" stroke="#333" stroke-width="1"/>
          <text x="${tick.x}" y="${printHeight -
              printPadding +
              15}" text-anchor="middle" font-size="10" fill="#333">${
              tick.label
            }</text>
        `
          )
          .join('')}
        
        <!-- Y轴刻度 -->
        ${yTicks
          .map(
            tick => `
          <line x1="${printPadding}" y1="${tick.y}" x2="${printPadding -
              5}" y2="${tick.y}" stroke="#333" stroke-width="1"/>
          <text x="${printPadding - 10}" y="${tick.y +
              4}" text-anchor="end" font-size="10" fill="#333">${
              tick.label
            }</text>
        `
          )
          .join('')}
        
        <!-- 折线图 -->
        <path d="${linePath}" fill="none" stroke="#ff4d4f" stroke-width="2"/>
        
        <!-- 数据点 -->
        ${chartPoints
          .map(
            (point, index) => `
          <circle cx="${point.x}" cy="${point.y}" r="3" fill="#ff4d4f" stroke="#fff" stroke-width="1"/>
        `
          )
          .join('')}
        
        <!-- 异常值标签 - 只在全局视图显示 -->
        ${
          this.zoomMode === 'global'
            ? chartPoints
                .map((point, index) => {
                  if (this.isOutlier(index)) {
                    const value = this.getOriginalValue(index);
                    const labelY = this.getPrintLabelY(
                      point.y,
                      value,
                      printHeight,
                      printPadding
                    );
                    return `
                <text x="${
                  point.x
                }" y="${labelY}" text-anchor="middle" font-size="10" fill="#ff4d4f" font-weight="bold">
                  ${value.toFixed(1)}°C
                </text>
              `;
                  }
                  return '';
                })
                .filter(label => label !== '')
                .join('')
            : ''
        }
      </svg>
    `;
  }

  // 生成打印用的刻度
  generatePrintTicks(
    min: number,
    max: number,
    size: number,
    padding: number,
    axis: 'x' | 'y'
  ): Array<{ x?: number; y?: number; label: string }> {
    const range = max - min;
    const tickCount = Math.floor(size / 80); // 每80像素一个刻度
    const step = range / tickCount;

    const ticks = [];
    for (let i = 0; i <= tickCount; i++) {
      const value = min + i * step;
      const position = padding + (i / tickCount) * size;

      if (axis === 'x') {
        ticks.push({
          x: position,
          label: this.formatTimeLabel(value)
        });
      } else {
        ticks.push({
          y: position,
          label: `${value.toFixed(3)}°C`
        });
      }
    }

    return ticks;
  }

  // 导出为图片
  exportAsImage(): void {
    const svgElement = this.$el.querySelector('.grid-svg') as SVGElement;
    if (!svgElement) {
      console.error('无法找到图表元素');
      return;
    }

    // 创建canvas
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    if (!ctx) {
      console.error('无法创建画布');
      return;
    }

    // 设置canvas尺寸
    canvas.width = this.containerWidth;
    canvas.height = this.containerHeight;

    // 设置白色背景
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 将SVG转换为图片
    const svgData = new XMLSerializer().serializeToString(svgElement);
    const svgBlob = new Blob([svgData], {
      type: 'image/svg+xml;charset=utf-8'
    });
    const svgUrl = URL.createObjectURL(svgBlob);

    const img = new Image();
    img.onload = () => {
      // 绘制图片到canvas
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

      // 转换为图片并下载
      canvas.toBlob(blob => {
        if (blob) {
          const url = URL.createObjectURL(blob);
          const link = document.createElement('a');
          link.href = url;
          link.download = `温度变化趋势图_${
            this.timeRange
          }_${new Date().toISOString().slice(0, 10)}.png`;
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
          URL.revokeObjectURL(url);
        }
      }, 'image/png');

      URL.revokeObjectURL(svgUrl);
    };

    img.src = svgUrl;
  }

  // 组件挂载后初始化
  mounted(): void {
    // 初始化默认日期
    this.endDate = new Date();
    this.startDate = new Date(this.endDate.getTime() - 24 * 60 * 60 * 1000); // 默认1天前

    // 使用nextTick确保DOM完全渲染后再更新尺寸
    this.$nextTick(() => {
      this.updateContainerSize();
    });
    window.addEventListener('resize', this.updateContainerSize);
  }

  // 组件销毁前清理
  beforeDestroy(): void {
    window.removeEventListener('resize', this.updateContainerSize);
  }

  // 更新容器尺寸
  updateContainerSize(): void {
    if (this.chartContainer) {
      const rect = this.chartContainer.getBoundingClientRect();
      // 使用容器的实际尺寸，但确保最小尺寸
      this.containerWidth = Math.max(1200, rect.width);
      this.containerHeight = Math.max(800, rect.height);

      // 调试信息：输出实际尺寸
      console.log('容器尺寸:', rect.width, 'x', rect.height);
      console.log('图表尺寸:', this.containerWidth, 'x', this.containerHeight);
    }
  }
}
</script>

<style lang="scss" scoped>
.line-chart-container {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f5f5;
  overflow: hidden;
  min-height: 800px;
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 24px;
  background: white;
  border-bottom: 1px solid #e8e8e8;

  h3 {
    margin: 0;
    color: #333;
    font-size: 18px;
  }

  .zoom-controls {
    display: flex;
    align-items: center;
    gap: 12px;

    .time-range-selector {
      display: flex;
      align-items: center;
      gap: 8px;

      label {
        color: #666;
        font-size: 14px;
      }

      select {
        padding: 4px 8px;
        border: 1px solid #d9d9d9;
        border-radius: 4px;
        font-size: 12px;
        background: white;
        cursor: pointer;

        &:hover {
          border-color: #40a9ff;
        }
      }
    }

    .date-range-selector {
      display: flex;
      align-items: center;
      gap: 8px;
      margin-left: 16px;

      label {
        color: #666;
        font-size: 12px;
      }

      input[type='date'] {
        padding: 4px 8px;
        border: 1px solid #d9d9d9;
        border-radius: 4px;
        font-size: 12px;
        background: white;
        cursor: pointer;

        &:hover {
          border-color: #40a9ff;
        }
      }
    }

    .zoom-mode-selector {
      display: flex;
      gap: 4px;
      margin-left: 16px;

      button {
        padding: 4px 8px;
        border: 1px solid #d9d9d9;
        border-radius: 4px;
        font-size: 11px;
        background: white;
        color: #333;
        cursor: pointer;
        transition: all 0.2s ease;
        min-width: 60px;

        &:hover {
          border-color: #40a9ff;
          background: #f0f8ff;
          color: #1890ff;
        }

        &.active {
          background: #1890ff;
          color: white;
          border-color: #1890ff;
        }
      }
    }

    span {
      color: #666;
      font-size: 14px;
    }

    button {
      padding: 6px 12px;
      background: #1890ff;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 12px;

      &:hover {
        background: #40a9ff;
      }
    }
  }
}

.chart-wrapper {
  flex: 1;
  overflow: visible;
  cursor: grab;
  background: white;
  margin: 16px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  min-width: 1200px;
  min-height: 700px;

  &:active {
    cursor: grabbing;
  }
}

.grid-svg {
  width: 100%;
  height: 100%;
  display: block;
}

.axes {
  stroke: #333;
  stroke-width: 2;
}

.ruler-marks {
  text {
    font-family: Arial, sans-serif;
    font-size: 12px;
    fill: #333;
  }
}

.line-chart {
  path {
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  circle {
    cursor: pointer;
    transition: r 0.2s ease;

    // &:hover {
    //   r: 6;
    // }
  }

  .tooltip {
    position: absolute;
    background: rgba(0, 0, 0, 0.8);
    color: white;
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    pointer-events: none;
    z-index: 1000;
    transform: translate(-50%, -100%);
  }

  .drawing-info-table {
    position: absolute;
    bottom: 20px;
    right: 20px;
    display: block;
    font-size: 10px;
    border: 1px solid #333;
    background: rgba(255, 255, 255, 0.95);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

    table {
      border-collapse: collapse;
      width: 200px;
      background: white;

      td {
        border: 1px solid #333;
        padding: 2px 4px;
        text-align: center;

        &.label {
          background: #f0f0f0;
          font-weight: bold;
          width: 30%;
        }

        &.value {
          background: white;
          width: 20%;
        }
      }
    }
  }

  .drawing-info-header {
    margin: 0 16px 4px 16px;
    padding: 6px 12px;
    background: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 4px;
    flex-shrink: 0;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

    .drawing-info-editable {
      display: flex !important;
      flex-wrap: wrap !important;
      gap: 6px 10px !important;
      align-items: center !important;
      justify-content: center !important;

      .info-item {
        display: flex !important;
        align-items: center !important;
        min-width: 120px !important;
        flex: 0 0 auto !important;

        label {
          font-size: 10px;
          font-weight: bold;
          color: #555;
          min-width: 30px;
          margin-right: 3px;
          white-space: nowrap;
          flex-shrink: 0;
        }

        .editable-input {
          flex: 1;
          padding: 1px 3px;
          border: 1px solid #ccc;
          border-radius: 2px;
          font-size: 9px;
          background: white;
          min-width: 0;

          &:focus {
            outline: none;
            border-color: #1890ff;
            box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
          }
        }
      }
    }
  }

  /* 打印样式 */
  @media print {
    .line-chart-container {
      width: 100% !important;
      height: auto !important;
      background: white !important;
    }

    .chart-header {
      display: none !important;
    }

    .chart-wrapper {
      margin: 0 !important;
      box-shadow: none !important;
      border-radius: 0 !important;
      overflow: visible !important;
    }

    .grid-svg {
      width: 100% !important;
      height: auto !important;
    }

    /* 确保打印时颜色正确显示 */
    * {
      -webkit-print-color-adjust: exact !important;
      print-color-adjust: exact !important;
    }

    .drawing-info-header {
      display: none !important;
    }

    .drawing-info-table {
      display: block !important;
      position: absolute !important;
      bottom: 20px !important;
      right: 20px !important;
      font-size: 8px !important;
      z-index: 1000 !important;
      background: white !important;
      box-shadow: none !important;

      table {
        width: 180px !important;
        border: 1px solid #000 !important;

        td {
          border: 1px solid #000 !important;
          padding: 1px 2px !important;
          font-size: 8px !important;

          &.label {
            background: #f0f0f0 !important;
            font-weight: bold !important;
          }

          &.value {
            background: white !important;
          }
        }
      }
    }
  }
}
</style>
